﻿using System;
using System.Collections.Generic;
using System.Linq;
using UnityEngine;
using System.Collections;
using UnityEngine.UI;
using QxFramework.Utilities;

/// <summary>
/// 回合运行器，按顺序执行回合操作
/// </summary>
public class RoundManager : MonoSingleton<RoundManager>, IEventListener
{
    public GameObject Button;
    private State nextState;
    private bool IsStateWaiting;

    /// <summary>
    /// 每个状态注册的行动列表，常规情况下只需要用到表长
    /// </summary>
    private List<int> ActionsRegisted = new List<int>();

    public int EventPriority() { return 0; }

    /// <summary>
    /// 静止状态
    /// </summary>
    public State Steady = new State();
    /// <summary>
    /// 玩家的行动状态
    /// </summary>
    public State PlayerState = new State();
    /// <summary>
    /// 玩家使用道具生效状态
    /// </summary>
    public State ItemState = new State();
    /// <summary>
    /// 敌人行动状态
    /// </summary>
    public State EnemyState = new State();
    /// <summary>
    /// 方块移动旋转状态
    /// </summary>
    public State DiceState = new State();
    /// <summary>
    /// 地面判断状态
    /// </summary>
    public State GroundState = new State();
    /// <summary>
    /// 初始化各状态
    /// </summary>
    private void InitiateState()
    {
        //Data.Instance.LoadTable();
        Steady.ThisState = EventDef.Steady;
        Steady.NextState = PlayerState;

        PlayerState.ThisState = EventDef.PlayerTurn;
        PlayerState.NextState = ItemState;

        ItemState.ThisState = EventDef.ItemTurn;
        ItemState.NextState = EnemyState;

        EnemyState.ThisState = EventDef.EnemyTurn;
        EnemyState.NextState = DiceState;

        DiceState.ThisState = EventDef.FlipCheckTurn;
        DiceState.NextState = GroundState;

        GroundState.ThisState = EventDef.FlipTurn;
        GroundState.NextState = Steady;


    }
    /// <summary>
    /// 接收消息行为
    /// </summary>
    /// <param name="id"></param>
    /// <param name="param1"></param>
    /// <param name="param2"></param>
    /// <returns></returns>
    public bool HandleEvent(int id, object param1, object param2)
    {
        if (Mathf.Abs(id) == EventDef.Action)
            RegisteAct(id);
        return false;
    }
    /// <summary>
    /// 注册与注销行动
    /// </summary>
    /// <param name="id"></param>
    /// <returns></returns>
    private int RegisteAct(int id)
    {
        if (id > 0)//登录消息
        {
            ActionsRegisted.Add(id);
            //Debug.Log("<color=#191970>" + "注册行为" + id + ", ActionsRegisted表长" + ActionsRegisted.Count + "</color>");
        }
        else if (id < 0)//注销消息
        {
            if (ActionsRegisted.Contains(-id))
            {
                ActionsRegisted.Remove(-id);
                //Debug.Log("<color=#191970>" + "注销行为" + -id + ", ActionsRegisted表长" + ActionsRegisted.Count + "</color>");
            }
            else
            {
                Debug.Log("<color=#191970>" + "行为注销错误！无此行为：" + -id + ", ActionsRegisted表长" + ActionsRegisted.Count + "</color>");
            }
        }
        return ActionsRegisted.Count;
    }

    private void Awake()
    {
        InitiateState();
        IsStateWaiting = false;
    }
    //private void Update()
    //{
    //    Debug.LogWarning("ActionsRegisted表长" + ActionsRegisted.Count + " " + Time.time);
    //}

    private IEnumerator Turn(State thisState)
    {
        nextState = thisState.NextState;
        EventNodeCore.GetInstance().SendMessage(thisState.ThisState, null, null);// 发送开始广播
        yield return null;// 先等一帧

        int temp = 0;
        bool sended = false;
        if (ActionsRegisted.Count > 0)
        {
            Debug.Log("<color=#006400>" + "回合" + thisState.ThisState + "开始等待" + Time.time + "</color>");
            sended = true;
        }
        IsStateWaiting = true;
        while (ActionsRegisted.Count > 0)// 等待结束回执
        {
            temp++;
            yield return null;
            //Debug.LogError("等了1帧" + Time.time);
        }
        IsStateWaiting = false;
        //Debug.Log("结束" + Time.time + " 等待帧" + "等待循环" + temp + "次" + ", ActionsRegisted表长" + instance.ActionsRegisted.Count);

        EventNodeCore.GetInstance().SendMessage(-PlayerState.ThisState, null, null);//发送结束广播

        if (sended)
        {
            Debug.Log("<color=#006400>" + "回合" + thisState.ThisState + "结束" + Time.time + "</color>");
        }

        StartCoroutine(Turn(nextState));// 切换为下一个状态
    }


    public void GameRoundStart()
    {
        StartCoroutine(Turn(Steady));
        Button.SetActive(false);
    }

    private void Start()
    {
        if (EventNodeCore.GetInstance())
        {
            EventNodeCore.GetInstance().AttachEventListener(EventDef.Action, this);
            EventNodeCore.GetInstance().AttachEventListener(-EventDef.Action, this);
        }
    }

    private void OnDestroy()
    {
        if (EventNodeCore.GetInstance())
        {
            EventNodeCore.GetInstance().DetachEventListener(EventDef.Action, this);
            EventNodeCore.GetInstance().DetachEventListener(-EventDef.Action, this);
        }
    }

    public bool SetNextState(State next)
    {
        if (IsStateWaiting)
        {
            State nextstate = new State()
            {
                ThisState = EventDef.TempTurn,
                NextState = nextState
            };
            nextState = nextstate;
            return true;
        }
        return false;
    }

    /// <summary>
    /// 定义状态
    /// </summary>
    public class State
    {
        /// <summary>
        /// 当前状态名
        /// </summary>
        private int thisState;
        public int ThisState
        {
            get { return thisState; }
            set { thisState = value; }
        }

        //public State previousState;
        //public State PreviousState
        //{
        //    get { return previousState; }
        //    set { previousState = value; }
        //}

        /// <summary>
        /// 下一状态
        /// </summary>
        private State nextState;
        public State NextState
        {
            get { return nextState; }
            set { nextState = value; }
        }
        ///// <summary>
        ///// 构造时需指定该(int)状态和(State)下一状态
        ///// </summary>
        ///// <param name="ThisState"></param>
        ///// <param name="NextState"></param>
        //public State(int ThisState, State NextState)
        //{
        //    thisState = ThisState;
        //    nextState = NextState;
        //}
    }
}